#set( $symbol_pound = '#' )
#set( $symbol_dollar = '$' )
#set( $symbol_escape = '\' )
package ${package}.${artifactId};

import ${package}.api.MyApp;
import com.sun.sgs.app.*;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.logging.Level;
import java.util.logging.Logger;

public class MyServerUser
        implements Serializable, ManagedObject, ClientSessionListener {
    private static final long serialVersionUID = 1L;
    private static final Logger logger = Logger.getLogger(MyServerUser.class.getName());
    protected static final String BIND_FMT = "User.%s";
    private ManagedReference<ClientSession> currentSessionRef = null;
    private String name;

    public static MyServerUser loggedIn(ClientSession session) {
        String binding = String.format(BIND_FMT, session.getName());
        DataManager dataMgr = AppContext.getDataManager();
        MyServerUser user;
        try {
            user = (MyServerUser) dataMgr.getBinding(binding);
        } catch (NameNotBoundException ex) {
            user = new MyServerUser(binding);
            logger.log(Level.INFO, String.format("New user created: %s${symbol_escape}n", user));
            dataMgr.setBinding(binding, user);
        }
        user.setSession(session);
        return user;
    }

    private MyServerUser(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return getName();
    }

    protected ClientSession getSession() {
        if (currentSessionRef == null)
            return null;
        return currentSessionRef.get();
    }

    protected void setSession(ClientSession session) {
        DataManager dataMgr = AppContext.getDataManager();
        dataMgr.markForUpdate(this);
        if(session == null)
            currentSessionRef = null;
        else
            currentSessionRef = dataMgr.createReference(session);
        logger.log(Level.INFO, String.format("Set sessions for %s: %s${symbol_escape}n", this, session == null ? "null" : session.getName()));
    }

    @Override
    public void receivedMessage(ByteBuffer message) {
        try {
            String fromClient = MyApp.decode(message);
            String response = String.format("Client sent: %s${symbol_escape}n", fromClient);
            logger.log(Level.INFO, response);
            getSession().send(MyApp.encode(response));
        } catch (UnsupportedEncodingException e) {
            logger.log(Level.SEVERE, e.getMessage());
        }
    }

    @Override
    public void disconnected(boolean b) {
        setSession(null);
        logger.log(Level.INFO, String.format("Disconnected: %s${symbol_escape}n", this));
    }
}
